package com.cloopen.rest.sdk.utils;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;

import cn.demoncat.util.exception.BizRuntimeException;
import cn.demoncat.util.io.CloseUtil;

/**
 * 连接云通讯
 * 
 * @author 延晓磊
 *
 * @since 2019年8月19日
 */
@SuppressWarnings("deprecation")
public class CcopHttpClient {

	/**
	 * 请求
	 * 
	 * @param hostname
	 * @param protocol
	 * @param port
	 * @param scheme
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月19日
	 */
	public static DefaultHttpClient registerSSL(String hostname, String protocol, int port, String scheme){
		DefaultHttpClient httpclient = null;
		try {
			httpclient = new DefaultHttpClient();
			SSLContext ctx = SSLContext.getInstance(protocol);
			X509TrustManager tm = getX509();
			ctx.init(null, new TrustManager[] { tm }, new SecureRandom());
			SSLSocketFactory socketFactory = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			Scheme sch = new Scheme(scheme, port, socketFactory);
			httpclient.getConnectionManager().getSchemeRegistry().register(sch);
			return httpclient;
		} catch (Exception e) {
			// 关闭连接
			CloseUtil.close(httpclient);
			throw new BizRuntimeException("连接云通讯服务端失败", e);
		}
	}

	/**
	 * 获取X509(拆分方法)
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月19日
	 */
	private static X509TrustManager getX509() {
		return new X509TrustManager() {

			@Override
			public void checkClientTrusted(X509Certificate[] chain, String authType) {
				// 无操作
			}

			@Override
			public void checkServerTrusted(X509Certificate[] chain, String authType) {
				if ((chain == null) || (chain.length == 0))
					throw new IllegalArgumentException("null or zero-length certificate chain");
				if ((authType == null) || (authType.length() == 0))
					throw new IllegalArgumentException("null or zero-length authentication type");

				Principal principal;
				for (X509Certificate x509Certificate : chain) {
					principal = x509Certificate.getSubjectX500Principal();
					if (principal != null) {
						return;
					}
				}
				throw new RuntimeException("服务端证书验证失败！");
			}

			@Override
			public X509Certificate[] getAcceptedIssuers() {
				return new X509Certificate[0];
			}
		};
	}
}
